/*
Copyright 2009 Swivel4J

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package org.swivel4j.chart;

import java.io.StringReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;

/**
 * A Swivel chart's metadata.
 * @author Ken Weiner
 * @version $Id: Chart.java 2 2009-11-28 01:59:25Z kweiner $
 */
public class Chart {
    private Integer id;
    private String name;
    private String description;
    private String options;
    private String secret;
    private String source;
    private Integer frequency;
    private Boolean groupWritable;
    private Integer adapterId;
    private Date createdAt;
    private Date updatedAt;
    private Date dataUpdatedAt;

    public Chart(String xml) {
        try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			InputSource inStream = new InputSource();
			inStream.setCharacterStream(new StringReader(xml));
			Document doc = db.parse(inStream);
			Element chartE = doc.getDocumentElement();
			this.id = (Integer) parseElement((Element) chartE.getElementsByTagName("id").item(0));
			this.name = (String) parseElement((Element) chartE.getElementsByTagName("name").item(0));
			this.description = (String) parseElement((Element) chartE.getElementsByTagName("description").item(0));
			this.options = (String) parseElement((Element) chartE.getElementsByTagName("options").item(0));
			this.secret = (String) parseElement((Element) chartE.getElementsByTagName("secret").item(0));
			this.source = (String) parseElement((Element) chartE.getElementsByTagName("source").item(0));
			this.frequency = (Integer) parseElement((Element) chartE.getElementsByTagName("frequency").item(0));
			this.groupWritable = (Boolean) parseElement((Element) chartE.getElementsByTagName("group-writable").item(0));
			this.adapterId = (Integer) parseElement((Element) chartE.getElementsByTagName("adapter-id").item(0));
			this.createdAt = (Date) parseElement((Element) chartE.getElementsByTagName("created-at").item(0));
			this.updatedAt = (Date) parseElement((Element) chartE.getElementsByTagName("updated-at").item(0));
			this.dataUpdatedAt = (Date) parseElement((Element) chartE.getElementsByTagName("data-updated-at").item(0));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
    }

    private Object parseElement(Element element) {
    	boolean isNil = Boolean.valueOf(element.getAttribute("nil")).booleanValue();
    	if (isNil) {
    		return null;
    	}
    	String text = element.getTextContent();
    	String type = element.getAttribute("type");
        if ("".equals(type)) {
        	return text;
        }
        if ("integer".equals(type)) {
        	return Integer.valueOf(text);
        }
        if ("boolean".equals(type)) {
        	return Boolean.valueOf(text);
        }
        if ("datetime".equals(type)) {
        	DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
            try {
            	int lastColon = text.lastIndexOf(":");
            	String dateString = text.substring(0, lastColon) + text.substring(lastColon + 1);
				return format.parse(dateString);
			} catch (ParseException e) {
				throw new RuntimeException(e);
			}
        }
        return null;
    }

	public Integer getId() {
		return id;
	}

	public String getName() {
		return name;
	}

	public String getDescription() {
		return description;
	}

	public String getOptions() {
		return options;
	}

	public String getSecret() {
		return secret;
	}

	public String getSource() {
		return source;
	}

	public Integer getFrequency() {
		return frequency;
	}

	public Boolean getGroupWritable() {
		return groupWritable;
	}

	public Integer getAdapterId() {
		return adapterId;
	}

	public Date getCreatedAt() {
		return createdAt;
	}

	public Date getUpdatedAt() {
		return updatedAt;
	}

	public Date getDataUpdatedAt() {
		return dataUpdatedAt;
	}

	public String toString() {
		return ToStringBuilder.reflectionToString(this);
	}
}
